home *** CD-ROM | disk | FTP | other *** search
- As a new Archimedes user, coming from the IBM PC environment I am familiar
- with the idea of a modifiable prompt as described in the Users Guide to
- provide an example of the use of the SETMACRO command.
-
- "SETMACRO CLI$PROMPT <SYS$TIME>" will provide the current time as a prompt
- by re-evaluating the prompt string each time it is used, and the SYS$TIME
- variable is maintained by the operating system. Personally I find the most
- useful information to have at the prompt is the path or current directory,
- especially since I have a hard disk. It is suprising that Arthur doesn't
- provide a system variable to keep track of the current directory. I decided
- to find out what is involved in creating and maintaining such a variable.
-
- The current directory is always changed, whether by a program or a command
- via the OS_FSControl SWI. When a SWI is issued by a program, control is
- passed via a "vector" or pointer, and this vector can be "claimed" or
- redirected to your own piece of code. It is then up to you whether you pass
- control on to the previous owner of the vector or "intercept" it entirely and
- replace the functions being requested with your own.
-
- The logic behind my program is as follows:
- - The program is entered via the claimed FSControlV vector.
- - If the function requested is not set current directory, then pass control
- onto the previous owner of the vector.
- - If set current directory(i.e. R0=0) is requested, then ensure that we regain
- control after the directory has been changed, by providing our return
- address pushed onto the stack.
- - On return we use the SWI OS_GBPB to "read current directory".
- - Then issue the OS_SetVarVal SWI to update the variable.
-
- Now if I am going to start interfering with the operating system by claiming
- vectors, I want to be sure that the memory into which I place my code is not
- going to inadvertently be overwritten by some application or utility. Else all
- functions provided by that SWI, and not just changing the current directory
- will be disabled! The ideal way to see that your interfering piece of code
- is well looked after, is to package it as a module.
-
- Other benefits of writing the program as a module are the ready made commands
- to install and remove it with RMLOAD and RMKILL, and predefined entry points
- for initialisation, finalisation and service call handler. The first two
- entry points are almost self explanatory, the initialisation code is called
- when the module is loaded and also after the RMA has been tidied. The
- finalisation code is entered for the OS_Module call with reason codes Tidy,
- Reinit, Delete and Clear, also if a module is loaded twice, the old one is
- killed.
-
- The use of the service call handler entry point is not as immediately
- obvious. Service calls are issued by OS_ServiceCall and are identified by the
- service number in R1. They fall into two categories either soliciting
- information or action because of an unknown - e.g. unknown file type,
- command, *status or OS_Word. Or else informing modules of an event that may
- be of interest to them - e.g. Error, StartUpFS, Reset, Keyboard handler, or
- Pre-reset.
-
- CurrDirRM was initially written without a service call handler, but the
- claimed vector was mysteriously being returned to its previous owner, which
- left the module useless and what was more annoying it was impossible to
- reinitialise, kill or tidy as it got an error whenever it tried to release a
- vector it no longer owned! I eventually saw the connection between, soft and
- machine resets and the "reset" vector. I used the service call handler to
- check for Reset and Pre-reset service calls, and set a flag to inform the
- finalisation code not to worry about releasing the vector.
-
- The module once assembled and saved to the modules directory, only occupies
- &13A bytes which even on a 512K system isn't too great a sacrifice. To
- install it and incorporate it into a prompt, add the following lines to your
- !BOOT program:
-
- *RMLOAD $.Modules.CurrDirRM
- *SETMACRO Cli$Prompt <Curr$Dir>==>
-